package com.solo.system.service.impl;

import cn.hutool.core.util.NumberUtil;
import com.solo.common.core.base.service.impl.BasicServiceImpl;
import com.solo.common.core.utils.StringUtils;
import com.solo.common.excel.listener.ExcelReadListener;
import com.solo.common.excel.utils.ExcelUtils;
import com.solo.system.api.entity.SysConfig;
import com.solo.system.mapper.SysConfigMapper;
import com.solo.system.model.config.SysConfigConvert;
import com.solo.system.model.config.req.ConfigCreateReq;
import com.solo.system.model.config.req.ConfigQueryReq;
import com.solo.system.model.config.req.ConfigUpdateReq;
import com.solo.system.model.config.resp.ConfigGetResp;
import com.solo.system.service.SysConfigService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Objects;

import static com.solo.common.core.utils.ServiceExceptionUtil.exception;
import static com.solo.system.api.consts.SystemCode.*;

/**
 * 系统配置表 Service实现类
 * @author 十一
 * @since 2023-10-18 16:33
 * 人生若只如初见，何事秋风悲画扇
 **/
@Service
@RequiredArgsConstructor
public class SysConfigServiceImpl extends BasicServiceImpl<SysConfigMapper, SysConfig> implements SysConfigService {

    private final SysConfigMapper sysConfigMapper;
    private final ExcelReadListener<SysConfig> salariesListener = new ExcelReadListener<>();

    @Override
    public boolean create(ConfigCreateReq req) {
        // 验证系统配置键是否唯一
        validateKeyUnique(req.getKey(), null);
        // 保存系统配置
        return save(SysConfigConvert.INSTANCE.convert(req));
    }

    @Override
    public boolean delete(Collection<Long> configIds) {
        for (Long configId : configIds) {
            // 验证系统配置是否存在
            SysConfig config = validateExists(configId);
            // 验证系统配置是否为内置类型
            validateIsSys(config.getIsSys());
            // TODO删除缓存
        }
        // 删除系统配置
        return removeByIds(configIds);
    }

    @Override
    public boolean update(ConfigUpdateReq req) {
        // 验证系统配置是否存在
        validateExists(req.getConfigId());
        // 验证系统配置键是否唯一
        validateKeyUnique(req.getKey(), req.getConfigId());
        // 更新系统配置
        return updateById(SysConfigConvert.INSTANCE.convert(req));
    }

    @Override
    public ConfigGetResp getConfigByKey(String key) {
        SysConfig config = sysConfigMapper.selectByKey(key);
        return SysConfigConvert.INSTANCE.convertGet(config);
    }

    @Override
    public void importExcel(MultipartFile file) throws IOException {
        ExcelUtils.read(file, SysConfig.class);
    }

    @Override
    public void exportExcel(HttpServletResponse response, ConfigQueryReq req) throws IOException {
        List<SysConfig> salaries = mapper.selectAll();
        ExcelUtils.write(response, "SysConfig", SysConfig.class, salaries);
    }

    /**
     * 验证系统配置是否存在
     * @param configId 配置id
     * @return {@link SysConfig }
     */
    SysConfig validateExists(Long configId) {
        if (configId == null) {
            return null;
        }
        SysConfig entity = mapper.selectOneById(configId);
        if (entity == null) {
            throw exception(CONFIG_NOT_EXISTS);
        }
        return entity;
    }

    /**
     * 验证系统配置键是否唯一
     * @param key 系统配置键
     * @param configId 配置id
     */
    void validateKeyUnique(String key, Long configId) {
        if (StringUtils.isEmpty(key)) {
            return;
        }
        SysConfig config = sysConfigMapper.selectByKey(key);
        if (!Objects.isNull(config) && !NumberUtil.equals(config.getConfigId(), configId)) {
            throw exception(CONFIG_KEY_EXISTS, key);
        }
    }

    /**
     * 验证系统配置是否为内置类型
     * @param isSys is sys
     */
    void validateIsSys(Boolean isSys) {
        if (isSys) {
            throw exception(CONFIG_CANT_DELETE_SYSTEM_TYPE);
        }
    }

}
